package com.artup.controller;

import java.io.InputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONObject;
import com.artup.common.Constants;
import com.artup.common.ResponseResult;
import com.artup.service.PayService;

/**
 * 支付
 * @author zhaojf
 * 2015年7月24日  上午10:38:46
 */
@Controller
@Scope(value = "prototype")
@RequestMapping( value = { "pay" } )
public class PayController {
	private static final Logger LOGGER = Logger.getLogger(PayController.class);
	@Autowired
	private PayService payService;
	private static Map<String, String> payResultMap = new HashMap<String, String>();

	/**
	 * 【微信支付】调用的接口
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "findWeChatPayResult")
	public void findWeChatPayResult(HttpServletRequest request, HttpServletResponse response, PrintWriter out) {
		long startTime = System.currentTimeMillis();
		LOGGER.info("PayController-findWeChatPayResult-startTime=" + startTime);
		response.setContentType("application/xml");
		
		Map<String, Object> payNoticeMap = null;
		try {
			payNoticeMap = this.parseXml(request);
		} catch (Exception e) {
			LOGGER.error("解析[微信支付二次验证]的 XML 通知失败！异常：", e);
		}
		
		LOGGER.info("payNoticeMap = " + JSONObject.toJSONString(payNoticeMap));
		String out_trade_no = (String) payNoticeMap.get("out_trade_no");
		
		ResponseResult resp = this.payService.findWeChatPayResult(payNoticeMap);
		payResultMap.put(out_trade_no, "uncompleted");
		
		String result = null;
		
		if(1 == resp.getStatus()){
			result = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[支付成功]]></return_msg></xml>";
			
			payResultMap.put(out_trade_no, "success");
		} else {
			result = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[支付失败]]></return_msg></xml>";

			payResultMap.put(out_trade_no, "failure");
		}
		
		out.println(result);
		out.flush();
		out.close();

		LOGGER.info("PayController-findWeChatPayResult-耗时=" + (System.currentTimeMillis() - startTime));
	}

	/**
	 * 支付宝支付调用的接口
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "findAliPayResult")
	public @ResponseBody String findAliPayResult(HttpServletRequest request) {
		long startTime = System.currentTimeMillis();
		LOGGER.info("PayController-findAliPayResult-startTime=" + startTime);
		
		String trade_status = request.getParameter("trade_status");		// 交易状态
		String out_trade_no = request.getParameter("out_trade_no");		// 商户订单号
		
		Map<String, Object> payNoticeMap = new HashMap<String, Object>();
		payNoticeMap.put("trade_status", trade_status);
		payNoticeMap.put("out_trade_no", out_trade_no);

		payResultMap.put(out_trade_no, "uncompleted");		// 验证未完成
		
		LOGGER.info("payNoticeMap = " + JSONObject.toJSONString(payNoticeMap));
		
		ResponseResult responseResult = this.payService.findAliPayResult(payNoticeMap);
		
		if(1 == responseResult.getStatus()){
			LOGGER.info("PayController-findAliPayResult-耗时=" + (System.currentTimeMillis() - startTime));
			
			payResultMap.put(out_trade_no, "success");
			
			return "success";
		} else {
			LOGGER.info("PayController-findAliPayResult-耗时=" + (System.currentTimeMillis() - startTime));
			
			payResultMap.put(out_trade_no, "failure");
			return "failure";
		}
	}
	
	/**
	 * 查询支付结果
	 * 【为 Android 设备】
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/background/pay/findPayResult4Android", method = RequestMethod.GET)
	public @ResponseBody ResponseResult findPayResult4Android(HttpServletRequest request) {
		long startTime = System.currentTimeMillis();
		LOGGER.info("PayController-findPayResult4Android-startTime=" + startTime);

		String orderCode = request.getParameter("orderCode");
		
		String payResult = payResultMap.get(orderCode);
		
		ResponseResult responseResult = new ResponseResult();
		responseResult.setStatus(Constants.ACTION_STATUS_SUCCESS);
		responseResult.setMessage("移动支付二次验证。");
		responseResult.setData(payResult);
		
		LOGGER.info("PayController-findPayResult4Android-耗时=" + (System.currentTimeMillis() - startTime));
		return responseResult;
	}

	@SuppressWarnings("unchecked")
	private Map<String, Object> parseXml(HttpServletRequest request)
			throws Exception {
		// 解析结果存储在HashMap
		InputStream inputStream = request.getInputStream();
		// 读取输入流
		SAXReader reader = new SAXReader();
		
		Document document = null;
		
		if(null != inputStream){
			document = reader.read(inputStream);
		}
		// 得到xml根元素
		Element root = null;
		if(null != document){
			root = document.getRootElement();
		}
		
		// 得到根元素的所有子节点
		List<Element> elementList = null;
		if(null != root){
			elementList = root.elements();
		}

		Map<String, Object> payNoticeMap = new HashMap<String, Object>();
		// 遍历所有子节点
		for (Element element : elementList){
			payNoticeMap.put(element.getName(), element.getText());
		}
		
		LOGGER.info("微信支付结果 = " + JSONObject.toJSONString(payNoticeMap));

		// 释放资源
		inputStream.close();
		inputStream = null;

		return payNoticeMap;
	}
}
